﻿using System.Diagnostics;
using EnvDTE;
using System;

namespace SolutionNavigateAddIn
{
    public static class SnEvents
    {

        private static SolutionEvents solutionEvents;
        private static SelectionEvents selectionEvents;
        private static CommandEvents unloadCommandEvents;
        private static CommandEvents reloadCommandEvents;
        private static CommandEvents openComboBoxCommandEvents;

        public static void Activate()
        {
            solutionEvents = SnEnvironment.MainDTE.Events.SolutionEvents;
            selectionEvents = SnEnvironment.MainDTE.Events.SelectionEvents;
            reloadCommandEvents = SnEnvironment.MainDTE.Events.get_CommandEvents("{5efc7975-14bc-11cf-9b2b-00aa00573819}", 412);
            unloadCommandEvents = SnEnvironment.MainDTE.Events.get_CommandEvents("{5efc7975-14bc-11cf-9b2b-00aa00573819}", 413);

            if (solutionEvents != null && selectionEvents != null)
            {
                solutionEvents.ProjectAdded += (ProjectAdded);
                solutionEvents.ProjectRemoved += (ProjectRemoved);
                solutionEvents.ProjectRenamed += (ProjectRenamed);
                solutionEvents.Opened += (SolutionOpened);
                solutionEvents.AfterClosing += (SolutionClosed);

                selectionEvents.OnChange += (OnChange);

                unloadCommandEvents.AfterExecute += (UnloadProject);
                reloadCommandEvents.AfterExecute += (ReloadProject);
            }
            else
            {
                Trace.TraceError("Solution events not registred.");
            }
        }

        public static void RegisterComboBoxCommand(Command command)
        {
            openComboBoxCommandEvents = SnEnvironment.MainDTE.Events.get_CommandEvents(command.Guid, command.ID);
            openComboBoxCommandEvents.AfterExecute += (openComboBoxCommand_AfterExecute);
        }

        private static void ReloadProject(string Guid, int ID, object CustomIn, object CustomOut)
        {
            if (LoadStateChanged != null)
            {
                LoadStateChanged(null, new ReloadUnloadEventArgs { State = ReloadUnloadEventArgs.EventState.Reload });
            }
        }

        private static void UnloadProject(string Guid, int ID, object CustomIn, object CustomOut)
        {
            if (LoadStateChanged != null)
            {
                LoadStateChanged(null, new ReloadUnloadEventArgs { State = ReloadUnloadEventArgs.EventState.Unload });
            }
        }

        private static void OnChange()
        {
            if (SelectionChanged != null)
            {
                SelectionChanged(null, EventArgs.Empty);
            }
        }

        private static void SolutionClosed()
        {
            if (SolutionStateChanged != null)
            {
                SolutionStateChanged(null, new SolutionEventArgs { State = SolutionEventArgs.SolutionState.Close });
            }
        }

        private static void SolutionOpened()
        {
            if (SolutionStateChanged != null)
            {
                SolutionStateChanged(null, new SolutionEventArgs { State = SolutionEventArgs.SolutionState.Open });
            }
        }

        private static void ProjectRenamed(Project Project, string OldName)
        {
            if (ProjectChanged != null)
            {
                ProjectChanged(null,
                               new ProjectEventArgs { Changes = ProjectEventArgs.ProjectChanged.Renamed, Project = Project });
            }
        }

        private static void ProjectRemoved(Project Project)
        {
            if (ProjectChanged != null)
            {
                ProjectChanged(null,
                               new ProjectEventArgs { Changes = ProjectEventArgs.ProjectChanged.Removed, Project = Project });
            }
        }

        private static void ProjectAdded(Project Project)
        {
            if (ProjectChanged != null)
            {
                ProjectChanged(null,
                               new ProjectEventArgs { Changes = ProjectEventArgs.ProjectChanged.Added, Project = Project });
            }
        }

        private static void openComboBoxCommand_AfterExecute(string Guid, int ID, object CustomIn, object CustomOut)
        {
            if (OpenComboBoxCommandExecuted != null)
            {
                OpenComboBoxCommandExecuted(null, EventArgs.Empty);
            }
        }

        public static event EventHandler<ReloadUnloadEventArgs> LoadStateChanged;

        public static event EventHandler<SolutionEventArgs> SolutionStateChanged;

        public static event EventHandler<ProjectEventArgs> ProjectChanged;

        public static event EventHandler OpenComboBoxCommandExecuted;

        public static event EventHandler SelectionChanged;

        public class ProjectEventArgs : EventArgs
        {

            public enum ProjectChanged
            {
                Added,
                Removed,
                Renamed,
            }

            public ProjectChanged Changes { get; set; }

            public Project Project { get; set; }

        }

        public class SolutionEventArgs : EventArgs
        {

            public enum SolutionState
            {
                Open,
                Close,
            }

            public SolutionState State { get; set; }

        }

        public class ReloadUnloadEventArgs : EventArgs
        {

            public enum EventState
            {
                Unload,
                Reload,
            }

            public EventState State { get; set; }

        }

    }
}